package com.spring.demo4.factory;

import com.spring.demo4.factory.Joinpoint.MyMethodInvocation;
import com.spring.demo4.factory.advice.MyAfterReturningAdvice;
import org.springframework.aop.AfterAdvice;
import org.springframework.util.Assert;

import java.io.Serializable;

/**
 * 2.AfterReturningAdviceInterceptor
 * 负责将 AfterReturningAdvice 方法后置通知包装为 MethodInterceptor 类型，创建这个类型的对象的时候需要传递一个 AfterReturningAdvice 类型的参数
 *
 * @author vhans
 */
public class MyAfterReturningAdviceInterceptor implements MyMethodInterceptor, AfterAdvice, Serializable {

    private final MyAfterReturningAdvice advice;

    public MyAfterReturningAdviceInterceptor(MyAfterReturningAdvice advice) {
        Assert.notNull(advice, "Advice must not be null");
        this.advice = advice;
    }

    @Override
    public Object invoke(MyMethodInvocation mi) throws Throwable {
        // 先执行方法调用链,可以获取目标方法的执行结果
        Object retVal = mi.proceed();
        // 执行后置通知
        this.advice.afterReturning(retVal, mi.getMethod(), mi.getArguments(), mi.getThis());
        return retVal;
    }
}
